package com.huangjue.backend.controller;

import com.huangjue.backend.entity.Course;
import com.huangjue.backend.entity.CourseStudy;
import com.huangjue.backend.entity.StudentCourse;
import com.huangjue.backend.service.CourseService;
import com.huangjue.backend.dto.CourseWithTeacherDTO;
import com.huangjue.backend.service.StudentCourseService;
import com.huangjue.backend.service.StudentService;
import com.huangjue.backend.entity.Student;
import com.huangjue.backend.service.UserService;
import com.huangjue.backend.entity.User;
import com.huangjue.backend.mapper.CertificateMapper;
import com.huangjue.backend.mapper.UserCertificateMapper;
import com.huangjue.backend.entity.Certificate;
import com.huangjue.backend.entity.UserCertificate;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.time.format.DateTimeFormatter;
import java.net.URLEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

import java.sql.SQLOutput;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/course")
@CrossOrigin(origins = "*")
public class CourseController {

    @Autowired
    private CourseService courseService;

    @Autowired
    private StudentCourseService studentCourseService;

    @Autowired
    private StudentService studentService;

    @Autowired
    private UserService userService;

    @Autowired
    private CertificateMapper certificateMapper;

    @Autowired
    private UserCertificateMapper userCertificateMapper;
    /**
     * 获取所有课程信息 - 首页接口
     */
    @GetMapping("/list")
    public ResponseEntity<Map<String, Object>> getAllCourses() {
        Map<String, Object> response = new HashMap<>();
        
        try {
            List<Course> courses = courseService.getAllCourses();
            response.put("success", true);
            response.put("message", "获取课程列表成功");
            response.put("data", courses);
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "获取课程列表失败: " + e.getMessage());
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /*
    * 获取推荐课程-首页展示
    * */
    @GetMapping("/recommendCourse")
    public ResponseEntity<Map<String, Object>> recommendCourse() {
        Map<String, Object> response = new HashMap<>();
        try {
            List<Course> courses = courseService.getRecommendCourse();
            response.put("success", true);
            response.put("message", "获取推荐课程列表成功");
            response.put("data", courses);
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "获取推荐课程列表失败: " + e.getMessage());
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /*
    * 搜索课程
    * */
    @GetMapping("/searchCourse")
    public ResponseEntity<Map<String, Object>> getCoursesByName(@RequestParam("keyword") String keyword) {
        Map<String, Object> response = new HashMap<>();
        
        // 参数验证
        if (keyword == null || keyword.trim().isEmpty()) {
            response.put("success", false);
            response.put("message", "搜索关键词不能为空");
            return ResponseEntity.badRequest().body(response);
        }
        
        try{
            List<Course> courses = courseService.getCoursesByKeywords(keyword.trim());
            response.put("success", true);
            response.put("message", "搜索课程成功");
            response.put("data", courses);
            return ResponseEntity.ok(response);
        }catch (Exception e){
            response.put("success", false);
            response.put("message", "搜索课程失败: "+e.getMessage());
            return ResponseEntity.internalServerError().body(response);
        }
    }

    @GetMapping("/allWithTeacher")
    public ResponseEntity<Map<String, Object>> getAllCoursesWithTeacher() {
        Map<String, Object> response = new HashMap<>();
        try {
            List<CourseWithTeacherDTO> courses = courseService.getAllCoursesWithTeacher();
            response.put("data", courses);
            response.put("message", "获取课程及老师信息成功");
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            response.put("message", "获取课程及老师信息失败: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }

    @GetMapping("/teacher/{teacherId}")
    public ResponseEntity<Map<String, Object>> getCoursesByTeacherId(@PathVariable Integer teacherId) {
        Map<String, Object> response = new HashMap<>();
        try {
            List<Course> courses = courseService.getCoursesByTeacherId(teacherId);
            response.put("success", true);
            response.put("data", courses);
            response.put("message", "获取老师课程成功");
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "获取老师课程失败: " + e.getMessage());
            return ResponseEntity.internalServerError().body(response);
        }
    }

    @GetMapping("/by-category/{categoryId}")
    public List<Course> getCoursesByCategory(@PathVariable Integer categoryId) {
        return courseService.getCoursesByCategoryId(categoryId);
    }

    /**
     * 用户选择课程，插入course_study表
     */
    @PostMapping("/chooseCourse")
    public ResponseEntity<Map<String, Object>> selectCourse(@RequestParam("userId") Integer userId,@RequestParam("courseId") Integer courseId) {
        Map<String, Object> response = new HashMap<>();
        try {
            if (userId == null || courseId == null) {
                response.put("success", false);
                response.put("message", "userId和courseId不能为空");
                return ResponseEntity.badRequest().body(response);
            }
            // 检查是否已存在
            Boolean is_exist = studentCourseService.isChooseCourse(userId, courseId);
            if (is_exist) {
                response.put("success", false);
                response.put("message", "您已选择过该课程");
                return ResponseEntity.ok(response);
            }
            //未选择过这门课，新增一条数据信息
            Boolean isSuccess = studentCourseService.chooseCourse(userId, courseId);
            if (!isSuccess) {
                response.put("success", false);
                response.put("message", "选课失败");
                return ResponseEntity.ok(response);
            }
            //解锁第一个demo，增加学生课程表中关于demo学习内容
            StudentCourse sc = new StudentCourse();
            sc.setUserId(userId);
            sc.setCourseId(courseId);
            sc.setDemoNum(0);
            sc.setDemoUnlock(1); // 默认解锁第一个demo
            int result = studentCourseService.save(sc);
            response.put("success", result > 0);
            response.put("message", result > 0 ? "选择课程成功" : "选择课程失败");
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "选择课程失败: " + e.getMessage());
            return ResponseEntity.internalServerError().body(response);
        }
    }

    @GetMapping("/getUserCourses/{userId}")
    public ResponseEntity<Map<String, Object>> getUserCourses(@PathVariable Integer userId) {
        Map<String, Object> response = new HashMap<>();
        try {
            List<StudentCourse> courses = courseService.getUserCourses(userId);
            response.put("success", true);
            response.put("data", courses);
            response.put("message", "获取用户课程成功");
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "获取用户课程失败: " + e.getMessage());
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /**
     * 获取课程完成状态
     */
    @GetMapping("/finished-status/{userId}/{courseId}")
    public ResponseEntity<Map<String, Object>> getCourseFinishedStatus(
            @PathVariable("userId") Integer userId,
            @PathVariable("courseId") Integer courseId) {
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            StudentCourse sc = studentCourseService.getByUserIdAndCourseId(userId, courseId);
            boolean isFinished = false;
            
            if (sc != null && sc.getDemoUnlock() != null && sc.getDemoNum() != null) {
                isFinished = sc.getDemoNum() >= sc.getDemoUnlock();
            }
            
            response.put("success", true);
            response.put("isFinished", isFinished);
            response.put("message", isFinished ? "课程已完成" : "课程未完成");
            
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "获取课程完成状态失败: " + e.getMessage());
        }
        
        return ResponseEntity.ok(response);
    }

    /**
     * 获取用户所有课程的完成状态
     */
    @GetMapping("/user-courses-status/{userId}")
    public ResponseEntity<Map<String, Object>> getUserCoursesStatus(@PathVariable("userId") Integer userId) {
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            List<StudentCourse> userCourses = courseService.getUserCourses(userId);
            List<Map<String, Object>> coursesWithStatus = new java.util.ArrayList<>();
            
            for (StudentCourse sc : userCourses) {
                Map<String, Object> courseStatus = new HashMap<>();
                courseStatus.put("courseId", sc.getCourseId());
                courseStatus.put("courseName", sc.getCourseName());
                courseStatus.put("demoNum", sc.getDemoNum());
                courseStatus.put("demoUnlock", sc.getDemoUnlock());
                
                // 检查课程是否完成
                boolean isFinished = false;
                if (sc.getDemoUnlock() != null && sc.getDemoNum() != null) {
                    isFinished = sc.getDemoNum() >= sc.getDemoUnlock();
                }
                courseStatus.put("isFinished", isFinished);
                
                coursesWithStatus.add(courseStatus);
            }
            
            response.put("success", true);
            response.put("data", coursesWithStatus);
            response.put("message", "获取用户课程状态成功");
            
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "获取用户课程状态失败: " + e.getMessage());
        }
        
        return ResponseEntity.ok(response);
    }

    /**
     * 更新课程浏览量
     */
    @PostMapping("/updateViews/{courseId}")
    public ResponseEntity<Map<String, Object>> updateCourseViews(@PathVariable Integer courseId) {
        Map<String, Object> response = new HashMap<>();
        try {
            boolean success = courseService.updateCourseViews(courseId);
            response.put("success", success);
            response.put("message", success ? "更新浏览量成功" : "更新浏览量失败");
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "更新浏览量失败: " + e.getMessage());
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /**
     * 更新课程点赞数111
     */
    @PostMapping("/updateLikes/{courseId}")
    public ResponseEntity<Map<String, Object>> updateCourseLikes(@PathVariable Integer courseId) {
        Map<String, Object> response = new HashMap<>();
        try {
            boolean success = courseService.updateCourseLikes(courseId);
            response.put("success", success);
            response.put("message", success ? "更新点赞数成功" : "更新点赞数失败");
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "更新点赞数失败: " + e.getMessage());
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /**
     * 下载课程证书
     */
    @GetMapping("/certificate/{userId}/{courseId}")
    public ResponseEntity<byte[]> downloadCertificate(
            @PathVariable("userId") Integer userId,
            @PathVariable("courseId") Integer courseId) {
        try {
            // 认证校验
            Student student = studentService.getStudentByUserId(userId);
            if (student == null || student.getIsAuthenticate() == null || student.getIsAuthenticate() != 1) {
                return ResponseEntity.status(HttpStatus.FORBIDDEN).body("只有认证学生才能下载证书".getBytes(StandardCharsets.UTF_8));
            }
            // 完成校验
            StudentCourse sc = studentCourseService.getByUserIdAndCourseId(userId, courseId);
            if (sc == null || sc.getDemoUnlock() == null || sc.getDemoNum() == null || sc.getDemoNum() < sc.getDemoUnlock()) {
                return ResponseEntity.status(HttpStatus.FORBIDDEN).body("课程未完成".getBytes(StandardCharsets.UTF_8));
            }

            // 取证书模板与用户证书记录
            Certificate certTpl = certificateMapper.selectEnabled();
            if (certTpl == null) {
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("未配置证书模板".getBytes(StandardCharsets.UTF_8));
            }
            UserCertificate userCert = userCertificateMapper.selectByUserIdAndCourseId(Long.valueOf(userId), courseId);
            if (userCert == null) {
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("未找到证书记录".getBytes(StandardCharsets.UTF_8));
            }

            // 获取用户与课程信息
            User user = userService.getUserById(userId);
            Course course = courseService.getCourseById(courseId);
            String userName = (student != null && student.getStudentName() != null && !student.getStudentName().isEmpty())
                    ? student.getStudentName()
                    : (user != null && user.getNickname() != null ? user.getNickname() : String.valueOf(userId));
            String courseTitle = course != null && course.getTitle() != null ? course.getTitle() : ("课程" + courseId);
            String title = certTpl.getCertTitle() != null ? certTpl.getCertTitle() : "课程结业证书";
            String certNo = userCert.getCertNo();
            String issueDate = (userCert.getIssueDate() != null ? userCert.getIssueDate() : java.time.LocalDateTime.now())
                    .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

            // 加载背景图
            String bgPath = certTpl.getBackgroundImage() != null ? certTpl.getBackgroundImage() : "http://localhost:8080/uploads/certificate/moren.jpg";
            BufferedImage bgImage = null;
            if (bgPath != null) {
                bgImage = tryLoadImage(bgPath);
            }
            if (bgImage == null) {
                // 如果背景图加载失败，尝试加载默认的moren.jpg
                bgImage = tryLoadImage("http://localhost:8080/uploads/certificate/moren.jpg");
                if (bgImage == null) {
                    // 最后的fallback: 生成白底
                    bgImage = new BufferedImage(1240, 1754, BufferedImage.TYPE_INT_RGB); // A4 300dpi近似
                    Graphics2D g0 = bgImage.createGraphics();
                    g0.setColor(Color.WHITE); g0.fillRect(0,0,bgImage.getWidth(), bgImage.getHeight());
                    g0.dispose();
                }
            }

            // 绘制文字
            BufferedImage canvas = new BufferedImage(bgImage.getWidth(), bgImage.getHeight(), BufferedImage.TYPE_INT_RGB);
            Graphics2D g = canvas.createGraphics();
            g.drawImage(bgImage, 0, 0, null);
            enableAa(g);

            int w = canvas.getWidth();
            int h = canvas.getHeight();

            // 标题 - 使用金色，更大字体
            g.setColor(new Color(139, 69, 19)); // 深棕色，更正式
            g.setFont(new Font("Microsoft YaHei", Font.BOLD, Math.max(48, w/16)));
            drawCenter(g, title, w/2, (int)(h*0.25));

            // 主体文案 - 分多行显示，更清晰
            g.setFont(new Font("Microsoft YaHei", Font.PLAIN, Math.max(32, w/24)));
            g.setColor(new Color(51, 51, 51)); // 深灰色
            
            // 第一行：兹证明
            String line1 = "兹证明";
            drawCenter(g, line1, w/2, (int)(h*0.40));
            
            // 第二行：学生姓名
            g.setFont(new Font("Microsoft YaHei", Font.BOLD, Math.max(36, w/20)));
            g.setColor(new Color(139, 69, 19)); // 深棕色突出姓名
            String line2 =student.getSchool()+" "+userName;
            drawCenter(g, line2, w/2, (int)(h*0.48));
            
            // 第三行：课程信息
            g.setFont(new Font("Microsoft YaHei", Font.PLAIN, Math.max(30, w/26)));
            g.setColor(new Color(51, 51, 51));
            String line3 = "已圆满完成《" + courseTitle + "》课程学习";
            if (line3.length() <= 22) {
                drawCenter(g, line3, w/2, (int)(h*0.56));
            } else {
                // 智能换行，避免标点在行首或行尾
                String[] lines = smartSplitText(line3, 22);
                drawCenter(g, lines[0], w/2, (int)(h*0.56));
                if (lines.length > 1) {
                    drawCenter(g, lines[1], w/2, (int)(h*0.64));
                }
            }

            
            // 第四行：结业说明
            String line4 = "经考核合格，特发此证，以资鼓励";
            if (line3.length() > 22) {
                drawCenter(g, line4, w/2, (int)(h*0.72));
            } else {
                drawCenter(g, line4, w/2, (int)(h*0.64));
            }


            // 编号与日期 - 更小的字体，底部显示
            g.setFont(new Font("Microsoft YaHei", Font.PLAIN, Math.max(24, w/40)));
            g.setColor(new Color(128, 128, 128)); // 中灰色
            drawLeft(g, "证书编号：" + (certNo==null?"N/A":certNo), (int)(w*0.15), (int)(h*0.88));
            drawRight(g, "颁发日期：" + issueDate, (int)(w*0.85), (int)(h*0.88));

            // 添加装饰性分隔线
            g.setColor(new Color(139, 69, 19));
            g.setStroke(new BasicStroke(2.0f));
            int lineY = (int)(h*0.78);
            g.drawLine((int)(w*0.20), lineY, (int)(w*0.80), lineY);

            g.dispose();

            // 输出为PNG
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(canvas, "png", baos);
            byte[] bytes = baos.toByteArray();

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.IMAGE_PNG);
            String fileName = userName + "_" + courseTitle + "_结课证书.png";
            String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
            headers.set("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"; filename*=UTF-8''" + encodedFileName);
            return ResponseEntity.ok().headers(headers).body(bytes);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(("证书生成失败: " + e.getMessage()).getBytes(StandardCharsets.UTF_8));
        }
    }

    /**
     * 检查用户是否已选择课程
     */
    @GetMapping("/is-chosen/{userId}/{courseId}")
    public ResponseEntity<Map<String, Object>> isCourseChosen(
            @PathVariable("userId") Integer userId,
            @PathVariable("courseId") Integer courseId) {
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            StudentCourse sc = studentCourseService.getByUserIdAndCourseId(userId, courseId);
            boolean isChosen = sc != null;
            
            response.put("success", true);
            response.put("isChosen", isChosen);
            response.put("message", isChosen ? "已选择课程" : "未选择课程");
            
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "检查课程选择状态失败: " + e.getMessage());
        }
        
        return ResponseEntity.ok(response);
    }

    /**
     * 获取学生的所有证书
     */
    @GetMapping("/user-certificates/{userId}")
    public ResponseEntity<Map<String, Object>> getUserCertificates(@PathVariable("userId") Integer userId) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            List<Map<String, Object>> certificates = new java.util.ArrayList<>();
            
            // 获取用户的所有证书记录
            List<UserCertificate> userCerts = userCertificateMapper.selectByUserId(Long.valueOf(userId));
            
            for (UserCertificate userCert : userCerts) {
                Map<String, Object> certInfo = new HashMap<>();
                
                // 获取课程信息
                Course course = courseService.getCourseById(userCert.getCourseId());
                if (course != null) {
                    certInfo.put("courseId", userCert.getCourseId());
                    certInfo.put("courseTitle", course.getTitle());
                    certInfo.put("certNo", userCert.getCertNo());
                    certInfo.put("issueDate", userCert.getIssueDate());
                    certInfo.put("isValid", userCert.getIsValid());
                    certificates.add(certInfo);
                }
            }
            
            response.put("success", true);
            response.put("data", certificates);
            response.put("message", "获取用户证书成功");
            
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "获取用户证书失败: " + e.getMessage());
        }
        
        return ResponseEntity.ok(response);
    }

    // 尝试多路径加载图片
    private BufferedImage tryLoadImage(String path) {
        try {
            File f1 = new File(path.startsWith("/")?"."+path:path);
            if (f1.exists()) return ImageIO.read(f1);
            File f2 = new File("src/main/resources/static" + (path.startsWith("/")?path:"/"+path));
            if (f2.exists()) return ImageIO.read(f2);
            File f3 = new File("uploads" + (path.startsWith("/")?path:"/"+path));
            if (f3.exists()) return ImageIO.read(f3);
        } catch (Exception ignored) {}
        return null;
    }

    private void enableAa(Graphics2D g) {
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    }

    private void drawCenter(Graphics2D g, String text, int cx, int y) {
        FontMetrics fm = g.getFontMetrics();
        int x = cx - fm.stringWidth(text)/2;
        g.drawString(text, x, y);
    }
    private void drawLeft(Graphics2D g, String text, int x, int y) {
        g.drawString(text, x, y);
    }
    private void drawRight(Graphics2D g, String text, int x, int y) {
        FontMetrics fm = g.getFontMetrics();
        int xx = x - fm.stringWidth(text);
        g.drawString(text, xx, y);
    }

    // 智能换行，避免标点在行首或行尾
    private String[] smartSplitText(String text, int maxLineLength) {
        if (text.length() <= maxLineLength) {
            return new String[]{text};
        }
        
        // 定义标点符号
        String punctuation = "，。！？；：\u201c\u201d''（）【】《》、";
        
        // 寻找最佳分割点
        int splitPoint = maxLineLength;
        
        // 从maxLineLength开始向前查找合适的分割点
        for (int i = maxLineLength; i >= maxLineLength - 5 && i > 0; i--) {
            char c = text.charAt(i - 1);
            // 如果当前字符是标点，且不是行首，则在此分割
            if (punctuation.indexOf(c) != -1 && i > 1) {
                splitPoint = i;
                break;
            }
            // 如果下一个字符是标点，则在此分割（避免标点在行首）
            if (i < text.length() && punctuation.indexOf(text.charAt(i)) != -1) {
                splitPoint = i;
                break;
            }
        }
        
        // 如果没找到合适的分割点，强制在maxLineLength处分割
        if (splitPoint == maxLineLength) {
            splitPoint = maxLineLength;
        }
        
        String firstLine = text.substring(0, splitPoint);
        String secondLine = text.substring(splitPoint);
        
        // 去除第二行开头的标点符号
        while (secondLine.length() > 0 && punctuation.indexOf(secondLine.charAt(0)) != -1) {
            secondLine = secondLine.substring(1);
        }
        
        if (secondLine.isEmpty()) {
            return new String[]{firstLine};
        } else {
            return new String[]{firstLine, secondLine};
        }
    }
} 